package com.frinder.official.akka.actors;

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.Terminated;
import com.frinder.official.spring.Actors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

/**
 * Created by frinder on 2017/9/13.
 * <p>
 * WatchActor 主要说明注册一个 Actor的方法，
 * 如：将 child注册到 WatchActor只需要 WatchActor.getContext().watch(child)即可，此时，WatchActor即可以 stop child
 */
@Component
@Scope("prototype")
public class WatchActor extends AbstractActor {

    @Autowired
    private Actors actors;

    private final ActorRef child = getContext().actorOf(Props.empty(), "target");

    private ActorRef lastSender = actors.getDeadLetters();

    public WatchActor() {
        /**
         * 1、child 注册到 WatchActor
         */
        getContext().watch(child); // <-- this is the only call needed for registration
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
                .matchEquals("kill", s -> {
                    /**
                     * 2、WatchActor 能 stop child
                     */
                    getContext().stop(child);
                    lastSender = getSender();
                })
                .match(Terminated.class, t -> t.actor().equals(child), t -> {
                    lastSender.tell("finished", getSelf());
                })
                .build();
    }
}
